package 语法

//闭包的关键字this owner delegate
//this 代表闭包定义所在的类
//owner 代表闭包定义处的类或者对象
//      闭包如果里面还包含闭包，里层的闭包那就是属于外层闭包了，而不是外层闭包所在的类
//delegate：任意的一个对象，有一个默认值就是和owner一致
//this和owner不可修改，delegate可以任意修改
def scriptClouser = {
    println "scriptClouser this:" + this;
    println "scriptClouser owner:" + owner;
    println "scriptClouser delegate:" + delegate;
    //这三个东西输出的结果一样
}
scriptClouser.call()
println "--------------------------------------"
//person相当于定义了一个内部类
class Person{
    //内部类中直接顶一个闭包
     def classClouser = {
         //指向person类
        println "classClouser this:" + this;
         //指向person类
        println "classClouser owner:" + owner;
         //指向person类
        println "classClouser delegate:" + delegate;
     }
    //内部类的方法中定义一个闭包
    def  say(){
        def classMethodClouser = {
            //指向person类
            println "classMethodClouser this:" + this;
            //指向person类
            println "classMethodClouser owner:" + owner;
            //指向person类
            println "classMethodClouser delegate:" + delegate;
            def classMethodInnerClouser = {
                //指向person类
                println "classMethodInnerClouser this:" + this;
                //指向外部闭包classMethodClouser
                println "classMethodInnerClouser owner:" + owner;
                //指向外部闭包classMethodClouser
                println "classMethodInnerClouser delegate:" + delegate;

            }
            classMethodInnerClouser.call()
        }
        classMethodClouser.call();
     }
}
Person p = new Person();
p.classClouser.call()
println "--------------------------------------"
p.say()
//输出结果都是一样都是内部类Person

println "--------------------------------------"
//闭包中还定义闭包
def nestClouser = {
     def innerClouser = {
         //指向当前所在的类
        println "innerClouser this:" + this;
         //指向外部的闭包nestClouser
        println "innerClouser owner:" + owner;
         //指向外部的闭包nestClouser
        println "innerClouser delegate:" + delegate;
    }
    innerClouser.call()
}
nestClouser.call()

println "--------------------------------------"
//修改delegate让其和owner不一样
//this和owner是不可以修改的，delegate可以任意的修改
def nestClouser001 = {
    def innerClouser001 = {
        //指向当前所在的类
        println "innerClouser001 this:" + this;
        //指向外部的闭包nestClouser
        println "innerClouser001 owner:" + owner;
         println "innerClouser001 delegate:" + delegate;
    }
    //人为修改默认的delegate，使其和owner不一样
    innerClouser001.delegate = p
    innerClouser001.call()
}
nestClouser001.call()
println "--------------------------------------"

//闭包的委托策略
class Student{
    String name
    def pretty = {"My name is ${name}"}
    String toString(){
        pretty.call()
    }
}

class Teacher{
    String name
}
def stu = new Student(name: 'stujml');
def tea = new Teacher(name: "teajml");
println stu.toString()
//现在打印的是stu的name，在不修改类代码的前提下怎么让其打印出teacher中name?
//将student的pretty闭包的delegate指向teacher
stu.pretty.delegate = tea
//delegate默认的委托策略是OWNER_FIRST，现在需要修改委托策略
//Closure.OWNER_FIRST是默认的表明闭包的变量方法首先从owner指向的对象去寻找
//Closure.DELEGATE_FIRST表明闭包的变量方法首先从delegate指向的对象去寻找，找不到就在去owner去寻找
//Closure.DELEGATE_ONLY表明闭包的变量方法只会从delegate指向的对象去寻找，如果没有就会报错
//这里delegate指向了teacher，所以会取teacher的变量和方法
stu.pretty.resolveStrategy = Closure.DELEGATE_FIRST
println stu.toString()
